import pandas as pd
import json
import os
import random

from PyQt5 import QtCore
import json


class Config:
    baseDir = QtCore.QStandardPaths.standardLocations(QtCore.QStandardPaths.DocumentsLocation)[0]
    _app_name = '复试系统'
    listenStuffDir = os.path.normpath(os.path.join(baseDir, _app_name, 'music'))
    problemDir = os.path.normpath(os.path.join(baseDir, _app_name, 'problem'))  # 专业问题
    studentDir = os.path.normpath(os.path.join(baseDir, _app_name, 'student'))

    listeningProblemDir = os.path.normpath(os.path.join(baseDir, _app_name, 'listening-problem'))  # 听力问题，听力文件和问题文件同名

    students = []
    listenStuff = []  # 只包含文件名称
    problems = []  # 问题的文件名称

    # 本次复试名称
    currentTestName = ''
    # 复试开始时间
    beginTime = None
    # 当前复试的学生
    currentStudent = None
    # 当前复试的学生序号
    currentStudentIndex = 0
    # 复试名单文件名
    studentFileName = 'st.xlsx'
    # 当前复试的学生已完成的进度，[0,1,2,3,4]
    currentPart = 1
    # 当前听力的名称
    currentListen = ''
    # 当前随机到的听力问题文本
    currentListenProblem = ''
    # 随机出来的专业问题文本
    problemTexts = []
    # 完成复试的学生序号
    completedStudentIndex = []
    # 跳过的学生序号
    skipedStudentIndex = []

    # 配置文件保存的名称
    configName = 'config.ini'

    # 录音文件的名称
    prefix = {1: '听力', 2: '自我介绍', 3: '专业提问', 4: '自由问答'}

    timeRecord = {'totalTime':0,'currentStudentTime':0}

    def __init__(self) -> None:
        pass

    @staticmethod
    def prepareStudent():
        data = pd.read_excel(os.path.join(Config.studentDir, Config.studentFileName), engine='openpyxl')
        data.head()
        res = data.to_json(orient='records')
        Config.students = json.loads(res)
        Config.currentStudent = Config.students[Config.currentStudentIndex]
        # parsed类似：
        # [{'id': 101839215412437,
        # '本科院校': '东北石油大学',
        # '本科专业': '石油工程',
        # '毕业年月': 201706,
        # '报考代码': '083500',
        # '英语分类': '英语一',
        # '数学分类': '数学二',
        # '专业课分类': '软件工程专业综合（数据结构、操作系统和计',
        # '报考院校': '吉林大学',
        # '报考专业': '软件工程',
        # '英语成绩': 50,
        # '政治成绩': 67,
        # '数学成绩': 127,
        # '专业课成绩': 133,
        # '总分': 377},...]

    @staticmethod
    def prepareListenStuff():
        Config.listenStuff = os.listdir(Config.listenStuffDir)  # 得到文件夹下的所有文件名称
        for i,val in enumerate(Config.listenStuff) :
            if val[0] == '.':
                del Config.listenStuff[i]

    @staticmethod
    def prepareProblems():
        Config.problems = os.listdir(Config.problemDir)  # 得到文件夹下的所有文件名称

    @staticmethod
    def nextStudent():
        Config.currentStudentIndex += 1
        if Config.currentStudentIndex == len(Config.students):
            return

        Config.currentStudent = Config.students[Config.currentStudentIndex]
        Config.currentPart = 0

    @staticmethod
    def randomListenStuff() -> str:
        index = random.randint(0, len(Config.listenStuff) - 1)
        Config.currentListen = Config.listenStuff[index]
        return Config.currentListen

    @staticmethod
    def randomProblem():
        Config.problemTexts = []
        for name in Config.problems:
            path = os.path.join(Config.problemDir, name)
            with open(path, 'r', encoding='utf-8') as f:
                # 读取文件所有行
                row_list = f.readlines()
                # 对行洗牌
                random.shuffle(row_list)
                # 去除末尾"\n"，添加题目
                Config.problemTexts.append(row_list[0].rstrip('\n'))

    @staticmethod
    def randomListeningProblem():
        textName = Config.currentListen.split('.')[0] + '.txt'
        if not textName:
            raise RuntimeError('textName为空，Config.currentListen是' + Config.currentListen)

        path = os.path.join(Config.listeningProblemDir, textName)
        with open(path, 'r', encoding='utf-8') as f:
            # 读取文件所有行
            row_list = f.readlines()
            # 对行洗牌
            random.shuffle(row_list)
            # 去除末尾"\n"，添加题目
            Config.currentListenProblem = row_list[0].rstrip('\n')

    @staticmethod
    def getStudentName():
        return Config.currentStudent['id']

    @staticmethod
    def getAudioFilePrefix():
        return Config.prefix[Config.currentPart]

    # 获取系统base目录
    @staticmethod
    def getBaseDir():
        return os.path.normpath(os.path.join(Config.baseDir, Config._app_name))

    # 保存配置文件
    @staticmethod
    def saveConfig():
        d = {
            'currentTestName': Config.currentTestName,
            'currentStudentIndex': Config.currentStudentIndex,
            'currentPart': Config.currentPart,
            'completedStudentIndex': Config.completedStudentIndex,
            'skipedStudentIndex': Config.skipedStudentIndex,
            'timeRecord':Config.timeRecord,
            'beginTime':Config.beginTime
        }
        d_str = json.dumps(d)
        with open(os.path.join(Config.getBaseDir(), Config.configName), 'w') as f:
            f.write(d_str)

    @staticmethod
    def loadConfig():
        if os.path.exists(Config.getConfigFile()):
            with open(Config.getConfigFile(), 'r') as f:
                lines = f.readlines()[0]
                c = json.loads(lines)
                Config.beginTime = c['beginTime']
                Config.currentTestName = c['currentTestName']
                Config.currentStudentIndex = c['currentStudentIndex']
                Config.currentPart = c['currentPart']
                Config.completedStudentIndex = c['completedStudentIndex']
                Config.skipedStudentIndex = c['skipedStudentIndex']
                Config.timeRecord = c['timeRecord']
                Config.currentStudent = Config.students[Config.currentStudentIndex]
    # 删除配置文件
    @staticmethod
    def removeConfig():
        if os.path.exists(Config.getConfigFile()):
            os.remove(Config.getConfigFile())
        else:
            print('配置文件不存在')

    # 重制Config
    @staticmethod
    def resetConfig():
        Config.currentTestName = ''
        Config.currentStudentIndex = 0
        Config.currentPart = 1
        Config.completedStudentIndex = []
        Config.skipedStudentIndex = []
        Config.timeRecord = {'totalTime':0,'currentStudentTime':0}
        Config.beginTime=None

    # 获取配置文件path
    @staticmethod
    def getConfigFile():
        configFile = os.path.join(Config.getBaseDir(), Config.configName)
        return configFile